package com.qianfeng1.day7_连接池.dao;


import com.qianfeng1.day7_连接池.jdbc.ConnectionPool;
import com.qianfeng1.day8_wednesday.TableName;
import com.qianfeng1.day8_wednesday.User;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 作者：黎杭
 * 日期：2020/2/18
 */
public interface MapperDao<V> {
    public static final String DESC_TB = "desc ";

    // 有了反射，sql语句都不用写， 什么都不用写，直接调用方法即可！

    default V findByMapper(V obj) {
        Class cls = obj.getClass();
        String tbName = getTableName(cls);
        Connection connection = ConnectionPool.getConnection();
        Field[] declaredFields = cls.getDeclaredFields();
        StringBuffer buffer = new StringBuffer("select ");
        StringBuffer where = new StringBuffer();
        for (Field f : declaredFields) {
            buffer.append(camel4underline(f.getName())).append(",");
            f.setAccessible(true);
            try {
                Object o = f.get(obj);
                if (o != null) {
                    where.append(" and ").append(camel4underline(f.getName())).append("=").append("'").append(o).append("'");
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        buffer.delete(buffer.length() - 1, buffer.length());
        buffer.append(" from ").append(tbName);// 可以继续追加条件
        if (where.length() > 0) {
            where.delete(where.indexOf("and"), where.indexOf("and") + 3);
            System.err.println(where.toString());
            buffer.append(" where ").append(where);
        }

        String sql = buffer.toString();

        try {
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                V v = (V) cls.newInstance();
                for (Field f : declaredFields) {// 获取本类成员
                    String name = f.getName();// 成员名称
                    int index = resultSet.findColumn(camel4underline(name));// 查找 列名下标
                    Object object = resultSet.getObject(index, f.getType());
                    Method m = cls.getDeclaredMethod("set" + upperCase(name), f.getType());
                    m.invoke(v, object);
                }
                return v;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    default String getTableName(Class cls) {
        Annotation annotation = cls.getDeclaredAnnotation(TableName.class);
        if (annotation == null) {
            return " " + cls.getSimpleName().toLowerCase() + " ";
        } else {
            try {
                return " " + annotation.getClass().getDeclaredMethod("value").invoke(annotation).toString() + " ";
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    default String getTableName(V v) {
        return getTableName(v.getClass());
    }

    static String upperCase(String s) {
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }

    static String camel4underline(String param) {
        Pattern p = Pattern.compile("[A-Z]");
        if (param == null || param.equals("")) {
            return "";
        }
        StringBuilder builder = new StringBuilder(param);
        Matcher mc = p.matcher(param);
        int i = 0;
        while (mc.find()) {
            builder.replace(mc.start() + i, mc.end() + i, "_" + mc.group().toLowerCase());
            i++;
        }

        if ('_' == builder.charAt(0)) {
            builder.deleteCharAt(0);
        }
        return builder.toString();
    }

}
